home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / intrlib1.zip / INTR_GR.C < prev    next >
C/C++ Source or Header  |  1992-01-26  |  37KB  |  1,050 lines

  1. /******************************************************************************
  2. * Low level graphics routines.                              *
  3. *                                          *
  4. *                    Written by Gershon Elber,  Oct. 1990  *
  5. *******************************************************************************
  6. * Supported device:                                  *
  7. * 1. CGA.                                      *
  8. * 2. EGA/VGA.                                      *
  9. * 2. Hercules.                                      *
  10. * 2. Super VGA.                                      *
  11. *******************************************************************************
  12. * History:                                      *
  13. *  15 Oct 90 - Version 1.0 by Gershon Elber.                      *
  14. ******************************************************************************/
  15.  
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <math.h>
  19. #include <mem.h>
  20. #include <dos.h>
  21. #include <io.h>
  22. #include <graphics.h>
  23. #include <conio.h>
  24. #include <fcntl.h>
  25. #include <ctype.h>
  26. #include "intr_loc.h"
  27. #include "mousedrv.h"
  28. #include "intr_gr.h"
  29.  
  30. #define GR_LINE_LEN    80      /* Maximum chars read by GRGetGraphicLine. */
  31.  
  32. #define SVGA_SPECIAL    999         /* User installed BGI Super VGA driver. */
  33.  
  34. #define    POINT_SIZE 0.05                  /* Size of + marker drawn. */
  35. #define    POINT_TITLE 0.02       /* Distance between point title and + marker. */
  36.  
  37. #define    CURSOR_IMAGE_X  24
  38. #define    CURSOR_IMAGE_Y  24
  39.  
  40. #define CURSOR_TYPE_STACK_SIZE 20     /* Size of stack to save cursor types. */
  41. #define VIEW_PORT_STACK_SIZE 20        /* Depth of view port setting stack. */
  42. #define TEXT_SETTING_STACK_SIZE 10         /* Depth of text setting stack. */
  43.  
  44. #define MAP_UP_X(x)  ((((x) - GRPanFactorX) << GRZoomFactor) + GRWidth2)
  45. #define MAP_UP_Y(y)  ((((y) - GRPanFactorY) << GRZoomFactor) + GRHeight2)
  46. #define MAP_DN_X(x)  ((((x) - GRPanFactorX) >> GRIZoomFactor) + GRWidth2)
  47. #define MAP_DN_Y(y)  ((((y) - GRPanFactorY) >> GRIZoomFactor) + GRHeight2)
  48. #define INVMAP_UP_X(x)  ((((x) - GRWidth2) >> GRZoomFactor) + GRPanFactorX)
  49. #define INVMAP_UP_Y(y)  ((((y) - GRHeight2) >> GRZoomFactor) + GRPanFactorY)
  50. #define INVMAP_DN_X(x)  ((((x) - GRWidth2) << GRIZoomFactor) + GRPanFactorX)
  51. #define INVMAP_DN_Y(y)  ((((y) - GRHeight2) << GRIZoomFactor) + GRPanFactorY)
  52.  
  53. int GRScreenMaxX, GRScreenMaxY;     /* The maximum resolution of the screen. */
  54. int GRScreenMaxColors;              /* The maximum # of colors available. */
  55. IntrRType GRScreenAspect = 1.0; /* Screen aspect ratio (pixel width/height). */
  56. int GRCurrentCursorX, GRCurrentCursorY;          /* Cursor current position. */
  57. int GRFontName, GRFontSize;         /* Global information on font used. */
  58. int GRDrawText;            /* If can not zoom down text, force draw. */
  59. int GRGraphMode = 0, GRGraphDriver = 0;       /* What driver/mode are we in. */
  60.  
  61. static int GRScreenMaxX2, GRScreenMaxY2;      /* Half of maximum resolution. */
  62. static VoidPtr GRPutImage = NULL;     /* If not null, used to save getimage. */
  63. static char *GRBGIDriverPath = "";       /* Where to look for BGI drivers. */
  64. static char *CursorImageBuffer;                    /* Cursor shape. */
  65. static int ScreenCursorColor;        /* Graphic and text (in graphic screen). */
  66. static int OldStdOut;    /* So we could recover it when exit from graph mode. */
  67. static int GRScreenGraphicMode;
  68. static char GRSVGAUserName[10];
  69. static int GRSVGAUserMode = 1;
  70. static int GRTextSize = 1;    /* Current text size: 1 = 8x8, 2 = 16x16 etc.. */
  71. static int GRWidth2 = 100;
  72. static int GRHeight2 = 100;
  73. static int GRMinX = 0;
  74. static int GRMinY = 0;
  75. static int GRZoomFactor = 0;
  76. static int GRIZoomFactor = 0;
  77. static int GRPanFactorX = 0;
  78. static int GRPanFactorY = 0;
  79. static struct text_info TextInfo;   /* So we can restore starting text mode. */
  80. static int ViewPortStackPtr = 0;
  81. static struct viewporttype far ViewPortStack[VIEW_PORT_STACK_SIZE];
  82. static int TextSettingStackPtr = 0;
  83. static struct textsettingstype TextSettingStack[TEXT_SETTING_STACK_SIZE];
  84. IntrInt2PtrFunc GlblGetChFunc = IntrGetEventWait;
  85.  
  86. static int GRGetKey(void);
  87.  
  88. /****************************************************************************
  89. * Routine to be called for the user installed driver:                *
  90. ****************************************************************************/
  91. static int huge detectVGA(void)
  92. {
  93.     return GRSVGAUserMode;
  94. }
  95.  
  96. /****************************************************************************
  97. * Routine to install the Super VGA information.                    *
  98. * Note GraphDriver must be set to SVGA_SPECIAL for this to take affect.     *
  99. ****************************************************************************/
  100. void GRInstallSVGA(char *NameMode)
  101. {
  102.     char *p;
  103.  
  104.     p = strtok(NameMode, ".");
  105.     strcpy(GRSVGAUserName, p);
  106.  
  107.     p = strtok(NULL, ".");
  108.     sscanf(p, "%d", &GRSVGAUserMode);
  109.  
  110.     GRGraphDriver = SVGA_SPECIAL;
  111. }
  112.  
  113. /****************************************************************************
  114. * Routine to set the path to the BGI drivers location.                *
  115. ****************************************************************************/
  116. void GRSetBGIPath(char *BGIPath)
  117. {
  118.     GRBGIDriverPath = strdup(BGIPath);
  119. }
  120.  
  121. /****************************************************************************
  122. * Routine to set default driver (0 autodetect).                    *
  123. ****************************************************************************/
  124. void GRSetDefaultDriver(int GraphDriver)
  125. {
  126.     GRGraphDriver = GraphDriver;
  127. }
  128.  
  129. /****************************************************************************
  130. * Routine to reset all the system to starting condition    :            *
  131. ****************************************************************************/
  132. void GRInitGraph(void)
  133. {
  134.     int IsSVGA = FALSE;
  135.     int    i, j, GRScreenErrorCode;
  136.     unsigned char far
  137.         *BiosMode = (unsigned char far *) MK_FP(0x40, 0x49);
  138.  
  139.     if (GRScreenGraphicMode) return;
  140.     gettextinfo(&TextInfo);
  141.  
  142.     ViewPortStackPtr = 0;          /* Make sure view port stack is empty. */
  143.  
  144.     /* For some wierd reason, some machines waits much more than expected on */
  145.     /* the first delay. Lets do it now, so people will consider it part of   */
  146.     /* the initialization (make it a feature...)...                          */
  147.     delay(1);
  148.  
  149.     if (GRGraphDriver != SVGA_SPECIAL) {
  150.     if (GRGraphDriver == 0) {
  151.         /* Use autodetect feature of graphic library to see what we have.*/
  152.         detectgraph(&GRGraphDriver, &GRGraphMode);
  153.         if (GRGraphDriver < 0) {
  154.         IntrFatalError("Auto detect: No graphics device detected.");
  155.         }
  156.     }
  157.     }
  158.  
  159.     /* Put in the following any graphic driver specific setup: */
  160.     switch (GRGraphDriver) {
  161.     case CGA:
  162.         GRGraphMode = CGAHI;
  163.         break;
  164.     case ATT400:
  165.         GRGraphMode = ATT400HI;
  166.         break;
  167.     case EGA:
  168.         GRGraphMode = EGAHI;
  169.         break;
  170.     case EGA64:
  171.         GRGraphMode = EGA64HI;
  172.         break;
  173.     case EGAMONO:
  174.         GRGraphMode = EGAMONOHI;
  175.         break;
  176.     case HERCMONO:
  177.         GRGraphMode = HERCMONOHI;
  178.             /* Use 2nd page as aux mem! */
  179.         GRPutImage = (VoidPtr) MK_FP(0xb800, 0x0000);
  180.         break;
  181.     case VGA:
  182.         GRGraphMode = VGAHI;
  183.         break;
  184.     case SVGA_SPECIAL:
  185.         IsSVGA = TRUE;
  186.         installuserdriver(GRSVGAUserName, detectVGA);
  187.         GRGraphDriver = DETECT;
  188.         GRGraphMode = GRSVGAUserMode;
  189.         break;
  190.     default:
  191.         IntrFatalError("Requested graphic device is not supported");
  192.         break;
  193.     }
  194.  
  195.     initgraph(&GRGraphDriver, &GRGraphMode, GRBGIDriverPath);
  196.     if (IsSVGA)    GRGraphDriver = SVGA_SPECIAL;
  197.  
  198.     GRScreenErrorCode = graphresult();       /* Read result of initialization. */
  199.     if (GRScreenErrorCode != grOk) {           /* Error occured during init. */
  200.     IntrFatalError("Graphics System Error: can not intialize.");
  201.     }
  202.  
  203.     GRScreenMaxColors = getmaxcolor() + 1; /* Read maximum number of colors. */
  204.     ScreenCursorColor = (GRScreenMaxColors > 1 ? GRScreenMaxColors - 1 :
  205.                          GRScreenMaxColors);
  206.  
  207.     GRScreenMaxX = getmaxx();                 /* Read size of screen. */
  208.     GRScreenMaxY = getmaxy();
  209.     GRCurrentCursorX = GRScreenMaxX2 = GRScreenMaxX / 2;
  210.     GRCurrentCursorY = GRScreenMaxY2 = GRScreenMaxY / 2;
  211.     getaspectratio(&i, &j);            /* Read the hardware aspect. */
  212.     GRScreenAspect = ((IntrRType) i) / j;
  213.     setaspectratio(i, i);         /* Disable the aspect ratio affect. */
  214.  
  215.     GRFontName = DEFAULT_FONT;
  216.     GRFontSize = 1;
  217.  
  218.     /* Prepare the cursor (Arrow) image : */
  219.     cleardevice();
  220.     GRSetColor(ScreenCursorColor);
  221.     GRSetLineStyle(SOLID_LINE, 0, NORM_WIDTH);
  222.     GRSLine(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y);
  223.     j = CURSOR_IMAGE_X / 3;
  224.     for    (i = 1; i <= 7; i++) GRSLine(0, 0, j, j + i);/* Draw the arrow head. */
  225.     j = CURSOR_IMAGE_Y / 3;
  226.     for    (i = 1; i <= 7; i++) GRSLine(0, 0, j + i, j);
  227.  
  228.     CursorImageBuffer = _IntrMalloc(imagesize(0, 0, CURSOR_IMAGE_X,
  229.                             CURSOR_IMAGE_Y));
  230.     getimage(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y, CursorImageBuffer);
  231.  
  232.     GRClearAllScreen();
  233.  
  234.     GRSetSTextStyle(DEFAULT_FONT, HORIZ_DIR, 1);
  235.  
  236.     switch (GRGraphDriver) {
  237.         case CGA:
  238.         case ATT400:
  239.         case EGA:
  240.         case EGA64:
  241.         case EGAMONO:
  242.         case VGA:
  243.         MouseSetResolution(1000);
  244.         break;
  245.     case SVGA_SPECIAL:
  246.         MouseSetResolution(4000);
  247.         break;
  248.     case HERCMONO:
  249.         *BiosMode = 6;
  250.         /* Compensate on the text mode the mouse knows about as      */
  251.         /* hercules is not supported by the mouse driver!            */
  252.         MouseSetResolution(1000);
  253.         break;
  254.     }
  255.  
  256.     GRScreenGraphicMode = TRUE;
  257.     i = open("nul", O_WRONLY);      /* Redirect the stdout to nul: (no ^C...). */
  258.     fflush(stdout);
  259.     OldStdOut = dup(1);
  260.     dup2(i, 1);
  261.     close(i);
  262. }
  263.  
  264. /****************************************************************************
  265. * Routine to close and shutdown    graphic    mode :                    *
  266. ****************************************************************************/
  267. void GRCloseGraph(void)
  268. {
  269.     if (!GRScreenGraphicMode) return;
  270.     closegraph();              /* Return the system to text mode. */
  271.     GRScreenGraphicMode = FALSE;
  272.     dup2(OldStdOut, 1);            /* Recover stdout to its regular status. */
  273.     close(OldStdOut);
  274.  
  275.     textmode(TextInfo.currmode);
  276. }
  277.  
  278. /****************************************************************************
  279. * Routine to set line style parameters.                        *
  280. ****************************************************************************/
  281. void GRSetLineStyle(int LineStyle, unsigned int Pattern, int Thickness)
  282. {
  283.     setlinestyle(LineStyle, Pattern, Thickness);
  284. }
  285.  
  286. /****************************************************************************
  287. * Routine to set fill style parameters.                        *
  288. ****************************************************************************/
  289. void GRSetFillStyle(int Pattern, int Color)
  290. {
  291.     setfillstyle(Pattern, Color);
  292. }
  293.  
  294. /****************************************************************************
  295. * Routine to set write mode parameters.                        *
  296. ****************************************************************************/
  297. void GRSetWriteMode(int DrawMode)
  298. {
  299.     setwritemode(DrawMode);
  300. }
  301.  
  302. /****************************************************************************
  303. * Routine to set text horizontal and vertical justification.            *
  304. ****************************************************************************/
  305. void GRSetTextJustify(int HorizCenter, int VertCenter)
  306. {
  307.     settextjustify(HorizCenter, VertCenter);
  308. }
  309.  
  310. /****************************************************************************
  311. * Routine to set zoom factor for drawing.                    *
  312. *   Zoom factor of 0 means regular drawing while each inc/decremenet zooms  *
  313. * up/down respectively by a factor of 2.                    *
  314. ****************************************************************************/
  315. void GRSetZoomFactor(int ZoomFactor)
  316. {
  317.     GRZoomFactor = ZoomFactor;
  318.     GRIZoomFactor = -GRZoomFactor;
  319. }
  320.  
  321. /****************************************************************************
  322. * Routine to set pan factors for drawing space.                    *
  323. ****************************************************************************/
  324. void GRSetPanFactors(int PanFactorX, int PanFactorY)
  325. {
  326.     GRPanFactorX = PanFactorX;
  327.     GRPanFactorY = PanFactorY;
  328. }
  329.  
  330. /****************************************************************************
  331. * Routine to set text drawing parameters, in drawing space.            *
  332. ****************************************************************************/
  333. void GRSetTextStyle(int GRFontName, int Direction, int Size)
  334. {
  335.     GRTextSize = Size + GRZoomFactor;
  336.  
  337.     settextstyle(GRFontName, Direction, 1 << (MAX(GRTextSize, 1) - 1));
  338. }
  339.  
  340. /****************************************************************************
  341. * Routine to set text drawing parameters, in screen space.            *
  342. ****************************************************************************/
  343. void GRSetSTextStyle(int GRFontName, int Direction, int Size)
  344. {
  345.     settextstyle(GRFontName, Direction, Size);
  346. }
  347.  
  348. /****************************************************************************
  349. * Routine to set text drawing parameters.                    *
  350. ****************************************************************************/
  351. unsigned GRGetImageBufferSize(int x1, int y1, int x2, int y2)
  352. {
  353.     return imagesize(x1, y1, x2, y2);
  354. }
  355.  
  356. /****************************************************************************
  357. * Routine to set text drawing parameters.                    *
  358. ****************************************************************************/
  359. void GRGetImageBuffer(int x1, int y1, int x2, int y2, VoidPtr Buffer)
  360. {
  361.     getimage(x1, y1, x2, y2, Buffer);
  362. }
  363.  
  364. /****************************************************************************
  365. * Routine to set text drawing parameters.                    *
  366. ****************************************************************************/
  367. void GRPutImageBuffer(int x1, int y1, VoidPtr Buffer)
  368. {
  369.     putimage(x1, y1, Buffer, COPY_PUT);
  370. }
  371.  
  372. /****************************************************************************
  373. * Routine to XOR a rectangle area on screen using current color.        *
  374. ****************************************************************************/
  375. void GRXORRectangle(int x1, int y1, int x2, int y2)
  376. {
  377.     int i;
  378.     struct linesettingstype lineinfo;
  379.  
  380.     getlinesettings(&lineinfo);
  381.  
  382.     setwritemode(XOR_PUT);
  383.     setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
  384.  
  385.     for (i = y1; i <= y2; i++)
  386.     line(x1, i, x2, i);
  387.  
  388.     setwritemode(COPY_PUT);
  389.     setlinestyle(lineinfo.linestyle, lineinfo.upattern, lineinfo.thickness);
  390. }
  391.  
  392. /****************************************************************************
  393. * External reference for the mappings.                        *
  394. ****************************************************************************/
  395. int GRMapX(int x)
  396. {
  397.     return (GRZoomFactor > 0 ? MAP_UP_X(x) : MAP_DN_X(x)) + GRMinX;
  398. }
  399.  
  400. int GRMapY(int y)
  401. {
  402.     return (GRZoomFactor > 0 ? MAP_UP_Y(y) : MAP_DN_Y(y)) + GRMinY;
  403. }
  404.  
  405. /****************************************************************************
  406. * External reference for the inverse mapping.                        *
  407. ****************************************************************************/
  408. int GRInvMapX(int x)
  409. {
  410.     x -= GRMinX;
  411.     return (GRZoomFactor > 0 ? INVMAP_UP_X(x) : INVMAP_DN_X(x));
  412. }
  413.  
  414. int GRInvMapY(int y)
  415. {
  416.     y -= GRMinY;
  417.     return (GRZoomFactor > 0 ? INVMAP_UP_Y(y) : INVMAP_DN_Y(y));
  418. }
  419.  
  420. /****************************************************************************
  421. * Routine to draw a line, in Object spaces.                        *
  422. ****************************************************************************/
  423. void GRLine(int x1, int y1, int x2, int y2)
  424. {
  425.     if (GRZoomFactor > 0) {
  426.         moveto(MAP_UP_X(x1), MAP_UP_Y(y1));
  427.         lineto(MAP_UP_X(x2), MAP_UP_Y(y2));
  428.     }
  429.     else {
  430.         moveto(MAP_DN_X(x1), MAP_DN_Y(y1));
  431.         lineto(MAP_DN_X(x2), MAP_DN_Y(y2));
  432.     }
  433. }
  434.  
  435. /****************************************************************************
  436. * Routine to move to a new position, in Object space.                *
  437. ****************************************************************************/
  438. void GRMoveTo(int x, int y)
  439. {
  440.     if (GRZoomFactor > 0)
  441.         moveto(MAP_UP_X(x), MAP_UP_Y(y));
  442.     else
  443.         moveto(MAP_DN_X(x), MAP_DN_Y(y));
  444. }
  445.  
  446. /****************************************************************************
  447. * Routine to draw to a new position, in Object space.                *
  448. ****************************************************************************/
  449. void GRLineTo(int x, int y)
  450. {
  451.     if (GRZoomFactor > 0)
  452.         lineto(MAP_UP_X(x), MAP_UP_Y(y));
  453.     else
  454.         lineto(MAP_DN_X(x), MAP_DN_Y(y));
  455. }
  456.  
  457. /****************************************************************************
  458. * Routine to move to a new position, in Screen (pixels) space.            *
  459. ****************************************************************************/
  460. void GRSMoveTo(int x, int y)
  461. {
  462.     moveto(x, y);
  463. }
  464.  
  465. /****************************************************************************
  466. * Routine to draw to a new position, in Screen (pixels) space.            *
  467. ****************************************************************************/
  468. void GRSLineTo(int x, int y)
  469. {
  470.     lineto(x, y);
  471. }
  472.  
  473. /****************************************************************************
  474. * Routine to draw to a new position, in Screen (pixels) space.            *
  475. ****************************************************************************/
  476. void GRSLine(int x1, int y1, int x2, int y2)
  477. {
  478.     line(x1, y1, x2, y2);
  479. }
  480.  
  481. /****************************************************************************
  482. * Routine to move to a new position relative to current one, as in Object   *
  483. * space.                                    *
  484. ****************************************************************************/
  485. void GRMoveRel(int x, int y)
  486. {
  487.     if (GRZoomFactor > 0)
  488.     moverel(x << GRZoomFactor, y << GRZoomFactor);
  489.     else
  490.     moverel(x >> GRIZoomFactor, y >> GRIZoomFactor);
  491. }
  492.  
  493. /****************************************************************************
  494. * Routine to line to a new position relative to current one, as in Object   *
  495. * space.                                    *
  496. ****************************************************************************/
  497. void GRLineRel(int x, int y)
  498. {
  499.     if (GRZoomFactor > 0)
  500.     linerel(x << GRZoomFactor, y << GRZoomFactor);
  501.     else
  502.     linerel(x >> GRIZoomFactor, y >> GRIZoomFactor);
  503. }
  504.  
  505. /****************************************************************************
  506. * Routine to move to a new position relative to current one, as in Screen   *
  507. * space (pixel coords.).                            *
  508. ****************************************************************************/
  509. void GRSMoveRel(int x, int y)
  510. {
  511.     moverel(x, y);
  512. }
  513.  
  514. /****************************************************************************
  515. * Routine to line to a new position relative to current one, as in Screen   *
  516. * space (pixel coords.).                            *
  517. ****************************************************************************/
  518. void GRSLineRel(int x, int y)
  519. {
  520.     linerel(x, y);
  521. }
  522.  
  523. /****************************************************************************
  524. * Routine to draw a new polyline and fill it if Fill, in screen space.        *
  525. ****************************************************************************/
  526. void GRPoly(int n, int *Points, int Fill)
  527. {
  528.     int i, ii;
  529.  
  530.     if (GRZoomFactor > 0)
  531.         for (i = 0; i < n; i++) {
  532.         ii = i << 1;
  533.             Points[ii] = MAP_UP_X(Points[ii]);
  534.             Points[ii + 1] = MAP_UP_Y(Points[ii + 1]);
  535.      }
  536.     else
  537.         for (i = 0; i < n; i++) {
  538.         ii = i << 1;
  539.             Points[ii] = MAP_DN_X(Points[ii]);
  540.             Points[ii + 1] = MAP_DN_Y(Points[ii + 1]);
  541.      }
  542.  
  543.     if (Fill) {
  544.     /* There is a problem with BLACK color that fillpoly sometime does   */
  545.     /* not clear the border properly, so we need to redo it by drawpoly. */
  546.     fillpoly(n, Points);
  547.     drawpoly(n, Points);
  548.     }
  549.     else
  550.     drawpoly(n, Points);
  551. }
  552.  
  553. /****************************************************************************
  554. * Routine to draw a bar, in drawing space.                    *
  555. ****************************************************************************/
  556. void GRBar(int x1, int y1, int x2, int y2)
  557. {
  558.     if (GRZoomFactor > 0)
  559.     bar(MAP_UP_X(x1), MAP_UP_Y(y1), MAP_UP_X(x2), MAP_UP_Y(y2));
  560.     else
  561.     bar(MAP_DN_X(x1), MAP_DN_Y(y1), MAP_DN_X(x2), MAP_DN_Y(y2));
  562. }
  563.  
  564. /****************************************************************************
  565. * Routine to draw a bar, in screen space.                    *
  566. ****************************************************************************/
  567. void GRSBar(int x1, int y1, int x2, int y2)
  568. {
  569.     bar(x1, y1, x2, y2);
  570. }
  571.  
  572. /****************************************************************************
  573. * Routine to draw a circle, in drawing space.                    *
  574. ****************************************************************************/
  575. void GRCircle(int x, int y, int r)
  576. {
  577.     if (GRZoomFactor > 0)
  578.     circle(MAP_UP_X(x), MAP_UP_Y(y), r << GRZoomFactor);
  579.     else
  580.     circle(MAP_DN_X(x), MAP_DN_Y(y), r >> GRIZoomFactor);
  581. }
  582.  
  583. /****************************************************************************
  584. * Routine to draw an arc, in drawing space.                    *
  585. * As the Y axes is inverted the Angles should be inverted as well.        *
  586. ****************************************************************************/
  587. void GRArc(int x, int y, int StAngle, int EndAngle, int r)
  588. {
  589.     if (GRZoomFactor > 0)
  590.     arc(MAP_UP_X(x), MAP_UP_Y(y), -EndAngle, -StAngle, r << GRZoomFactor);
  591.     else
  592.     arc(MAP_DN_X(x), MAP_DN_Y(y), -EndAngle, -StAngle, r >> GRIZoomFactor);
  593. }
  594.  
  595. /****************************************************************************
  596. * Routine to draw the given text in given drawing space coordinates.        *
  597. ****************************************************************************/
  598. IntrBType GRDrawingText(void)
  599. {
  600.     return GRTextSize > 0 || GRDrawText;
  601. }
  602.  
  603. /****************************************************************************
  604. * Routine to draw the given text in given drawing space coordinates.        *
  605. ****************************************************************************/
  606. void GRText(int x, int y, char *s)
  607. {
  608.     /* If text can not be zoom down and we are not forced to draw - dont. */
  609.     if (GRTextSize < 1 && !GRDrawText) return;
  610.  
  611.     if (GRZoomFactor > 0)
  612.         outtextxy(MAP_UP_X(x), MAP_UP_Y(y), s);
  613.     else
  614.         outtextxy(MAP_DN_X(x), MAP_DN_Y(y), s);
  615. }
  616.  
  617. /****************************************************************************
  618. * Routine to draw the given text in given screen space coordinates.        *
  619. ****************************************************************************/
  620. void GRSText(int x, int y, char *s)
  621. {
  622.     outtextxy(x, y, s);
  623. }
  624.  
  625. /****************************************************************************
  626. * Routine to draw the given text in given screen space coordinates.        *
  627. * A Black shadow is drawn for the given string.                    *
  628. ****************************************************************************/
  629. void GRSTextShadow(int x, int y, int Color, char *s)
  630. {
  631.     GRSetColor(BLACK);
  632.     outtextxy(x + 2, y + 2, s);
  633.     GRSetColor(Color);
  634.     outtextxy(x, y, s);
  635. }
  636.  
  637. /****************************************************************************
  638. * Routine to get string width in pixel.                        *
  639. ****************************************************************************/
  640. int GRGetTextWidth(char *Str)
  641. {
  642.     return textwidth(Str);
  643. }
  644.  
  645. /****************************************************************************
  646. * Routine to get string height in pixel.                    *
  647. ****************************************************************************/
  648. int GRGetTextHeight(char *Str)
  649. {
  650.     return textheight(Str);
  651. }
  652.  
  653. /****************************************************************************
  654. * Routine to push current font type and text attributes.            *
  655. ****************************************************************************/
  656. void GRPushTextSetting(void)
  657. {
  658.     if (TextSettingStackPtr >= TEXT_SETTING_STACK_SIZE)
  659.     IntrFatalError("Text setting stack overflow.");
  660.  
  661.     gettextsettings(&TextSettingStack[TextSettingStackPtr++]);
  662. }
  663.  
  664. /****************************************************************************
  665. * Routine to pop current font type and text attributes.                *
  666. ****************************************************************************/
  667. void GRPopTextSetting(void)
  668. {
  669.     if (--TextSettingStackPtr < 0)
  670.     IntrFatalError("Text setting stack underflow.");
  671.  
  672.     settextstyle(TextSettingStack[TextSettingStackPtr].font,
  673.              TextSettingStack[TextSettingStackPtr].direction,
  674.          TextSettingStack[TextSettingStackPtr].charsize);
  675.     settextjustify(TextSettingStack[TextSettingStackPtr].horiz,
  676.            TextSettingStack[TextSettingStackPtr].vert);
  677. }
  678.  
  679. /****************************************************************************
  680. * Routine to set color to color within range.                    *
  681. ****************************************************************************/
  682. void GRSetColor(int Color)
  683. {
  684.     if (Color >= GRScreenMaxColors)
  685.     Color = Color % (GRScreenMaxColors - 1) + 1;
  686.     setcolor(Color);
  687. }
  688.  
  689. /****************************************************************************
  690. * Routine to get current active color.                        *
  691. ****************************************************************************/
  692. int GRGetColor(void)
  693. {
  694.     return getcolor();
  695. }
  696.  
  697. /****************************************************************************
  698. * Routine to set one color index RGB values (EGA/VGA only).            *
  699. ****************************************************************************/
  700. void GRSetRGBPalette(int Index, int Red, int Green, int Blue)
  701. {
  702.     setrgbpalette(Index, Red, Green, Blue);
  703. }
  704.  
  705. /****************************************************************************
  706. * Routine to draw a point on screen as marker +    with a title :            *
  707. ****************************************************************************/
  708. void GRPutArrowCursor(int x, int y)
  709. {
  710.     putimage(x, y, CursorImageBuffer, XOR_PUT);
  711. }
  712.  
  713. /****************************************************************************
  714. * Routine to draw a point on screen as marker +    with a title :            *
  715. ****************************************************************************/
  716. void GRDrawPoint(int x, int y, char title[], int PointColor)
  717. {
  718.     GRSetColor(PointColor);
  719.     GRSMoveTo(x + POINT_SIZE, y);
  720.     GRSLineTo(x - POINT_SIZE, y);
  721.     GRSMoveTo(x, y + POINT_SIZE);
  722.     GRSLineTo(x, y - POINT_SIZE);
  723.  
  724.     GRSText(x + POINT_TITLE, y + POINT_TITLE, title);
  725. }
  726.  
  727. /*****************************************************************************
  728. *   Routine to clear all the screen.                         *
  729. *****************************************************************************/
  730. void GRClearAllScreen(void)
  731. {
  732.     setviewport(0, 0, GRScreenMaxX, GRScreenMaxY, FALSE);
  733.     cleardevice();
  734. }
  735.  
  736. /*****************************************************************************
  737. *   Routine to clear given rectangle viewport.                     *
  738. *****************************************************************************/
  739. void GRClearViewPort(int x1, int y1, int x2, int y2)
  740. {
  741.     struct viewporttype viewport;
  742.  
  743.     getviewsettings(&viewport);
  744.  
  745.     setviewport(x1, y1, x2, y2, TRUE);
  746.     clearviewport();
  747.  
  748.     setviewport(viewport.left, viewport.top, viewport.right, viewport.bottom,
  749.                                 viewport.clip);
  750. }
  751.  
  752. /*****************************************************************************
  753. *   Routine to set given rectangle viewport.                     *
  754. *****************************************************************************/
  755. void _GRSetViewPort(int x1, int y1, int x2, int y2)
  756. {
  757.     setviewport(x1, y1, x2, y2, TRUE);
  758. }
  759.  
  760. /*****************************************************************************
  761. *   Routine to set given rectangle viewport.                     *
  762. *****************************************************************************/
  763. void _GRSetViewPort2(int x1, int y1, int x2, int y2, IntrBType Clip)
  764. {
  765.     setviewport(x1, y1, x2, y2, Clip);
  766. }
  767.  
  768. /*****************************************************************************
  769. *   Routine to set given rectangle viewport.                     *
  770. *****************************************************************************/
  771. void GRGetViewPort(int *x1, int *y1, int *x2, int *y2)
  772. {
  773.     struct viewporttype viewstruct;
  774.  
  775.     getviewsettings(&viewstruct);
  776.     *x1 = viewstruct.left;
  777.     *x2 = viewstruct.right;
  778.     *y1 = viewstruct.top;
  779.     *y2 = viewstruct.bottom;
  780. }
  781.  
  782. /*****************************************************************************
  783. *   Routine to set given rectangle viewport.                     *
  784. *****************************************************************************/
  785. void GRSetViewPort(int x1, int y1, int x2, int y2)
  786. {
  787.     setviewport(x1, y1, x2, y2, TRUE);
  788.     GRWidth2 = (x2 - x1) / 2;
  789.     GRHeight2 = (y2 - y1) / 2;
  790.     GRMinX = x1;
  791.     GRMinY = y1;
  792. }
  793.  
  794. /*****************************************************************************
  795. *   Routine to push current view port.                         *
  796. *****************************************************************************/
  797. void GRPushViewPort(void)
  798. {
  799.     if (ViewPortStackPtr >= VIEW_PORT_STACK_SIZE)
  800.     IntrFatalError("View port stack overflow.");
  801.  
  802.     getviewsettings(&ViewPortStack[ViewPortStackPtr++]);
  803. }
  804.  
  805. /*****************************************************************************
  806. *   Routine to pop current view port.                         *
  807. *****************************************************************************/
  808. void GRPopViewPort(void)
  809. {
  810.     if (--ViewPortStackPtr < 0)
  811.     IntrFatalError("View port stack underflow.");
  812.  
  813.     setviewport(ViewPortStack[ViewPortStackPtr].left,
  814.         ViewPortStack[ViewPortStackPtr].top,
  815.         ViewPortStack[ViewPortStackPtr].right,
  816.         ViewPortStack[ViewPortStackPtr].bottom,
  817.         ViewPortStack[ViewPortStackPtr].clip);
  818.     GRWidth2 = (ViewPortStack[ViewPortStackPtr].right -
  819.             ViewPortStack[ViewPortStackPtr].left) / 2;
  820.     GRHeight2 = (ViewPortStack[ViewPortStackPtr].bottom -
  821.              ViewPortStack[ViewPortStackPtr].top) / 2;
  822.     GRMinX = ViewPortStack[ViewPortStackPtr].left;
  823.     GRMinY = ViewPortStack[ViewPortStackPtr].top;
  824. }
  825.  
  826. /*****************************************************************************
  827. * Routine to read one line terminated by <Enter> and visualized    on graphic   *
  828. * screen.                                     *
  829. * Full line editing is supported which includes:                 *
  830. * 1. RGRht and left arrow to move along the line.                 *
  831. * 2. Delete to delete current character.                     *
  832. * 3. Insert to toggle Insert/Overwrite mode.                     *
  833. * 4. Backspace to delete character before current one.                 *
  834. * 5. Home/End to move to beginning/End of string respectively.             *
  835. * 6. Return to accept current line.                         *
  836. * 7. Esc to clear current line.                             *
  837. *                                         *
  838. * Notes:                                     *
  839. * If s is not empty it is used as starting string.                 *
  840. * Line is drawn    starting from position x, y on screen, WindowLen positions.  *
  841. * s buffer is assumed to be of SLen length.                     *
  842. *****************************************************************************/
  843. void GRGetGraphicLine(int WindowID, int x, int y, char s[], int SLen,
  844.               int WindowLen, int ForeColor, int BackColor)
  845. {
  846.     static int
  847.     Insert = TRUE;
  848.     int    NextKey, Xstep, xt,
  849.         CursorPos = 0,
  850.         FirstVisible = 0,
  851.         FirstTime = TRUE,
  852.         Len = strlen(s),
  853.     EndOfString = FALSE;
  854.     char DisplayLine[GR_LINE_LEN];
  855.     struct textsettingstype oldtext;
  856.     _IntrWindowStruct
  857.     *Window = WindowID ? _IntrFindWndwUsingID(WindowID) : NULL;
  858.  
  859.     CursorPos = Len;
  860.  
  861.     gettextsettings(&oldtext);
  862.     settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
  863.     settextjustify(LEFT_TEXT, TOP_TEXT);
  864.  
  865.     Xstep = textwidth("M");     /* Get the width in pixels of current font. */
  866.  
  867.     while (!EndOfString) {
  868.     /* Can not display the whole string, so set first visible char:  */
  869.     FirstVisible = CursorPos > WindowLen - 2 ? CursorPos - WindowLen + 2
  870.                          : 0;
  871.     /* Prepare the part of s to be displayed: */
  872.     strncpy(DisplayLine, &s[FirstVisible], GR_LINE_LEN - 1);
  873.     DisplayLine[WindowLen] = 0;
  874.  
  875.     GRSetColor(ForeColor);
  876.     outtextxy(x, y, DisplayLine);
  877.     xt = x + (CursorPos - FirstVisible) * Xstep;
  878.     if (Insert)
  879.         GRXORRectangle(xt, y + 7, xt + 7, y + 8);
  880.     else
  881.         GRXORRectangle(xt, y, xt + 7, y + 8);
  882.  
  883.     if ((NextKey = GRGetKey()) != KEY_REFRESH || FirstTime) {
  884.         if (Insert)
  885.             GRXORRectangle(xt, y + 7, xt + 7, y + 8);
  886.         else
  887.             GRXORRectangle(xt, y, xt + 7, y + 8);
  888.         GRSetColor(BackColor);     /* Erase the string and the cursor: */
  889.         outtextxy(x, y, DisplayLine);
  890.     }
  891.     FirstTime = FALSE;
  892.  
  893.     switch (NextKey) {
  894.         case KEY_BSPACE:
  895.         if (CursorPos == 0) {
  896.             GRTone(1000, 100);             /* Do some noise... */
  897.             break;
  898.         }
  899.         movmem(&s[CursorPos], &s[CursorPos - 1], Len - CursorPos + 1);
  900.         CursorPos--;
  901.         Len--;
  902.         break;
  903.         case KEY_DELETE:
  904.         if (CursorPos >= Len) {
  905.             GRTone(1000, 100);             /* Do some noise... */
  906.             break;
  907.         }
  908.         movmem(&s[CursorPos + 1], &s[CursorPos], Len - CursorPos);
  909.         Len--;
  910.         break;
  911.         case KEY_RIGHT:
  912.         if (CursorPos >= Len) {
  913.             GRTone(1000, 100);             /* Do some noise... */
  914.             break;
  915.         }
  916.         CursorPos++;
  917.         break;
  918.         case KEY_LEFT:
  919.         if (CursorPos <= 0) {
  920.             GRTone(1000, 100);             /* Do some noise... */
  921.             break;
  922.         }
  923.         CursorPos--;
  924.         break;
  925.         case KEY_RETURN:
  926.         EndOfString = TRUE;
  927.         break;
  928.         case KEY_ESC:
  929.         Len = 0;                    /* Clear everything. */
  930.         CursorPos = 0;
  931.         s[0] = 0;
  932.         break;
  933.         case KEY_HOME:
  934.         CursorPos = 0;
  935.         break;
  936.         case KEY_END:
  937.         CursorPos = Len;
  938.         break;
  939.         case KEY_INSERT:
  940.         Insert = !Insert;
  941.         break;
  942.         case KEY_NONE:
  943.             GRTone(1000, 100);             /* Do some noise... */
  944.         GRTone(500, 200);
  945.         break;
  946.         case KEY_REFRESH:              /* Internal event to intr_lib. */
  947.         if (Window != NULL) {
  948.             _GRSetViewPort(Window -> BBox.Xmin, Window -> BBox.Ymin,
  949.                        Window -> BBox.Xmax, Window -> BBox.Ymax);
  950.             x = TEXT_BORDER,
  951.                  y = Window -> BBox.Ymax - Window -> BBox.Ymin -
  952.                        TEXT_BORDER - GRGetTextHeight("M");
  953.         }
  954.         settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
  955.         settextjustify(LEFT_TEXT, TOP_TEXT);
  956.         break;
  957.         default:                      /* Regular ascii char. */
  958.         if (Insert) {
  959.             movmem(&s[CursorPos], &s[CursorPos + 1],
  960.                             Len - CursorPos + 1);
  961.             Len++;
  962.         }
  963.         else if (CursorPos == Len)
  964.             Len++;            /* We are on last character. */
  965.         s[CursorPos++] = NextKey;
  966.         if (CursorPos == Len) s[CursorPos] = 0;
  967.         break;
  968.     }
  969.     if (SLen <= Len - 1) {    /* End of buffer - can not save more info. */
  970.         Len = SLen - 1;
  971.         if (CursorPos > Len) CursorPos = Len;
  972.         GRTone(1000, 100);                 /* Do some noise... */
  973.     }
  974.     }
  975.  
  976.     settextstyle(oldtext.font, oldtext.direction, oldtext.charsize);
  977.     settextjustify(oldtext.horiz, oldtext.vert);
  978. }
  979.  
  980. /*****************************************************************************
  981. * Sets the function invoked to get a kbd event in GRGetKey.             *
  982. * NULL will recover the internal default - IntrGetEventWait.             *
  983. *****************************************************************************/
  984. void GRSetGetKeyFunc(IntrInt2PtrFunc GetChFunc)
  985. {
  986.     if (GetChFunc == NULL)
  987.     GlblGetChFunc = IntrGetEventWait;
  988.     else
  989.         GlblGetChFunc = GetChFunc;
  990. }
  991.  
  992. /*****************************************************************************
  993. * Get a key from keyboard, and translating operational keys into special     *
  994. * codes (>255).                                     *
  995. *****************************************************************************/
  996. static int GRGetKey(void)
  997. {
  998.     int x, y;
  999.  
  1000.     /* Detach the keyboard from moving the mouse so keyboard can be used to  */
  1001.     /* edit the input line instead.                         */
  1002.     _IntrDetachKbdFromMouse = TRUE;
  1003.     while (GlblGetChFunc(&x, &y) != INTR_EVNT_KEY);
  1004.     _IntrDetachKbdFromMouse = FALSE;
  1005.  
  1006.     if (x >= 256) {
  1007.     switch (x - 256) {    /* Extended code - get the next extended char. */
  1008.         case 75:
  1009.         return KEY_LEFT;
  1010.         case 77:
  1011.         return KEY_RIGHT;
  1012.         case 71:
  1013.         return KEY_HOME;
  1014.         case 79:
  1015.         return KEY_END;
  1016.         case 83:
  1017.         return KEY_DELETE;
  1018.         case 82:
  1019.         return KEY_INSERT;
  1020.         case KEY_REFRESH - 256:
  1021.         return KEY_REFRESH;
  1022.     }
  1023.     }
  1024.     else {
  1025.         switch (x) {
  1026.         case 8:
  1027.             return KEY_BSPACE;
  1028.         case 10:
  1029.         case 13:
  1030.             return KEY_RETURN;
  1031.         case 27:
  1032.             return KEY_ESC;
  1033.         default:
  1034.             if isprint(x) return x;
  1035.     }
  1036.     }
  1037.  
  1038.     return KEY_NONE;
  1039. }
  1040.  
  1041. /*****************************************************************************
  1042. * Routine to make some sound with given Frequency, Time milliseconds:         *
  1043. *****************************************************************************/
  1044. void GRTone(int Frequency, int Time)
  1045. {
  1046.     sound(Frequency);
  1047.     delay(Time);
  1048.     nosound();
  1049. }
  1050.